package com.imooc.utils;

import com.imooc.exceptions.GraceException;
import com.imooc.grace.result.ResponseStatusEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.PostConstruct;
import javax.crypto.SecretKey;
import java.util.Date;

/**
 * @author 啊昌
 * @date 2025/9/12 21:42
 * JWTUtils JWT工具类
 */
@Component
@Slf4j
@RefreshScope
@ConfigurationProperties(prefix = "jwt")
public class JWTUtils {
	@Autowired
	private JWTProperties jwtProperties;

	public static final String at = "@";
//	public static final String JWT_KEY = "imooc_123456789_123456789";

	@Value("${jwt.key}")
	public String JWT_KEY ; //从nacos 获取到jwt的key配置

	@PostConstruct
	public void init() {
		log.info(">>>> jwt.key=" + JWT_KEY);
	}

	public String createJWTWithPrefix(String body, Long expireTimes, String prefix) {
		if (expireTimes == null)
			GraceException.display(ResponseStatusEnum.SYSTEM_NO_EXPIRE_ERROR);

		return prefix + at + createJWT(body, expireTimes);
	}

	public String createJWTWithPrefix(String body, String prefix) {
		return prefix + at + createJWT(body);
	}

	public String createJWT(String body) {
		return dealJWT(body, null);
	}

	public String createJWT(String body, Long expireTimes) {
		if (expireTimes == null)
			GraceException.display(ResponseStatusEnum.SYSTEM_NO_EXPIRE_ERROR);

		return dealJWT(body, expireTimes);
	}

	public String dealJWT(String body, Long expireTimes) {

//        String userKey = jwtProperties.getKey();
		String userKey = JWT_KEY;
		log.info("Nacos jwt key = " + JWT_KEY);

		// 1. 对秘钥进行base64编码
		String base64 = new BASE64Encoder().encode(userKey.getBytes());

		// 2. 对base64生成一个秘钥的对象
		SecretKey secretKey = Keys.hmacShaKeyFor(base64.getBytes());

		String jwt = "";
		if (expireTimes != null) {
			jwt = generatorJWT(body, expireTimes, secretKey);
		} else {
			jwt = generatorJWT(body, secretKey);
		}
		log.info("JWTUtils - dealJWT: generatorJWT = " + jwt);

		return jwt;
	}

	public String generatorJWT(String body, SecretKey secretKey) {
		String jwtToken = Jwts.builder()
				.setSubject(body)
				.signWith(secretKey)
				.compact();
		return jwtToken;
	}

	/**
	 * 生成JWT令牌
	 * @param body JWT的主体内容
	 * @param expireTimes 过期时间（毫秒）
	 * @param secretKey 签名密钥
	 * @return 生成的JWT令牌字符串
	 */
	public String generatorJWT(String body, Long expireTimes, SecretKey secretKey) {
		// 定义过期时间
		Date expireDate = new Date(System.currentTimeMillis() + expireTimes);
		// 构建JWT令牌
		String jwtToken = Jwts.builder()
				.setSubject(body)
				.signWith(secretKey)
				.setExpiration(expireDate)
				.compact();
		return jwtToken;
	}


		/**
	 * 校验JWT令牌的有效性并返回其中的主体信息
	 *
	 * @param pendingJWT 待校验的JWT令牌字符串
	 * @return JWT令牌中的主体信息(subject)
	 * @throws Exception 当JWT令牌无效、过期或被篡改时抛出异常
	 */
	public String checkJWT(String pendingJWT) {

//        String userKey = jwtProperties.getKey();
		String userKey = JWT_KEY;
		log.info("Nacos jwt key = " + JWT_KEY);

		// 1. 对秘钥进行base64编码
		String base64 = new BASE64Encoder().encode(userKey.getBytes());

		// 2. 对base64生成一个秘钥的对象
		SecretKey secretKey = Keys.hmacShaKeyFor(base64.getBytes());

		// 3. 校验jwt
		JwtParser jwtParser = Jwts.parserBuilder()
				.setSigningKey(secretKey)
				.build();       // 构造解析器
		// 解析成功，可以获得Claims，从而去get相关的数据，如果此处抛出异常，则说明解析不通过，也就是token失效或者被篡改
		Jws<Claims> jws = jwtParser.parseClaimsJws(pendingJWT);      // 解析jwt

		String body = jws.getBody().getSubject();

		return body;
	}

}
